import {FormControl, FormGroup, NonNullableFormBuilder, Validators} from '@angular/forms';
import {Component, EventEmitter, Input, Output, OnInit} from '@angular/core';
import {EmployeeService} from "../employee.service"
import {Employee} from "../employee.type"
import {format} from "date-fns";
import {NzMessageService} from "ng-zorro-antd/message";
import { CLIENT_RENEG_LIMIT } from 'tls';



@Component({
  selector: 'app-employee-upload',
  templateUrl: './employee-upload.component.html',
})

/**
 * 员工上传组件类
 */
export class EmployeeUploadComponent implements OnInit {
  // 控制模态框显示
  visible = false;

  // 选中文件名
  fileName = '';

  // 原始解析出的表格数据（数组形式），第一行为表头
  parsedRows: string[][] = [];

  // 解析后要发送给后端的数据结构
  parsedPayload: { [key: string]: string } | null = null;

  // 将解析好的数据发给父组件或者外部处理器
  @Output() upload = new EventEmitter<{ [key: string]: string }>();
  @Output() cancelled = new EventEmitter<void>();

  constructor(private msg: NzMessageService) {
  }

  ngOnInit(): void {
    // 初始化逻辑
  }

  // 打开模态框
  open(): void {
    this.reset();
    this.visible = true;
  }

  // 关闭模态框
  close(): void {
    this.visible = false;
  }

  // 取消
  cancel(): void {
    this.close();
    this.cancelled.emit();
  }

  // 浏览按钮触发的文件选择处理
  onFileSelected(event: Event): void {
    const input = event.target as HTMLInputElement;
    if (!input.files || input.files.length === 0) {
      return;
    }
    const file = input.files[0];
    this.fileName = file.name;

    // 校验扩展名是否为 csv
    if (!/\.csv$/i.test(file.name)) {
      this.msg.error('只能上传 csv 文件');
      this.resetFileState();
      return;
    }

    const reader = new FileReader();
    reader.onload = () => {
      const text = reader.result as string;
      try {
        this.parseCSV(text);
        this.msg.success('CSV 文件解析成功');
      } catch (err) {
        this.msg.error('解析 CSV 失败：' + (err instanceof Error ? err.message : err));
        this.resetFileState();
      }
    };
    reader.onerror = () => {
      this.msg.error('读取文件失败');
      this.resetFileState();
    };
    reader.readAsText(file, 'utf-8');

    // 清空 input 的值，以便重复选择同一个文件也会触发 change
    input.value = '';
  }

  // 简单 CSV 解析器，支持带双引号的字段（含逗号），返回 rows 数组
  private parseCSV(text: string): void {
    // 统一换行符并拆行
    const lines = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n').filter(l => l.trim() !== '');
    if (lines.length === 0) {
      throw new Error('CSV 内容为空');
    }

    const rows: string[][] = lines.map(line => this.parseCSVLine(line));

    const headers = rows[0].map(h => h.trim());
    if (headers.length === 0) {
      throw new Error('未检测到表头');
    }

    // 校验每行列数至少与表头一致（允许末尾缺失值，但会补空字符串）
    for (let i = 1; i < rows.length; i++) {
      const r = rows[i];
      if (r.length < headers.length) {
        // 补齐空字符串
        while (r.length < headers.length) r.push('');
      }
    }

    this.parsedRows = rows;

    // 构造要发送的 payload：每个表头对应逗号拼接的所有值
    const payload: { [key: string]: string } = {};
    for (let col = 0; col < headers.length; col++) {
      const key = headers[col];
      const values: string[] = [];
      for (let r = 1; r < rows.length; r++) {
        values.push(rows[r][col] ? rows[r][col].trim() : '');
      }
      payload[key] = values.join(',');
    }

    this.parsedPayload = payload;
  }

  // 解析单行 CSV，支持双引号内逗号和双引号转义
  private parseCSVLine(line: string): string[] {
    const result: string[] = [];
    let cur = '';
    let inQuotes = false;
    for (let i = 0; i < line.length; i++) {
      const ch = line[i];
      if (inQuotes) {
        if (ch === '"') {
          // 双引号出现，可能是转义（""）或结束
          if (i + 1 < line.length && line[i + 1] === '"') {
            cur += '"';
            i++; // 跳过转义的双引号
          } else {
            inQuotes = false;
          }
        } else {
          cur += ch;
        }
      } else {
        if (ch === '"') {
          inQuotes = true;
        } else if (ch === ',') {
          result.push(cur);
          cur = '';
        } else {
          cur += ch;
        }
      }
    }
    result.push(cur);
    return result;
  }

  // 点击确定时触发，若解析成功则分批 emit 数据
  confirmUpload(): void {
    if (!this.parsedPayload) {
      this.msg.error('请先选择并解析 CSV 文件');
      return;
    }
    // 解析后的格式：{site: "GL,ZZ", product: "a1,a2", name: "name1,name2"}
    // 需要将每个字段拆分为数组，再按10条分批
    const keys = Object.keys(this.parsedPayload);
    if (keys.length === 0) {
      this.msg.error('数据格式错误');
      return;
    }
    // 拆分每个字段的值
    const columns = keys.map(k => (this.parsedPayload![k] ? this.parsedPayload![k].split(',') : []));
    console.log(columns)
    const total = columns[0].length;
    if (!columns.every(arr => arr.length === total)) {
      this.msg.error('各字段数据条数不一致');
      return;
    }
    // 按10条分批
    for (let i = 0; i < total; i += 10) {
      const batch: { [key: string]: string } = {};
      keys.forEach((k, idx) => {
        batch[k] = columns[idx].slice(i, i + 10).join(',');
      });
      console.log("batch",batch)
      this.upload.emit(batch);
    }
    this.msg.success(`已分批发送数据，共${Math.ceil(total/10)}次`);
    this.close();
  }

  // 下载模板（生成一个示例 CSV 并触发下载）
  downloadTemplate(): void {
    if (!this.parsedRows || this.parsedRows.length === 0) {
      // 给出一个默认模板
      const header = ['site', 'product', 'name'];
      const example = ['GL', 'a1', 'name1'];
      const example2 = ['ZZ', 'a2', 'name2'];
      const csv = [header.join(','), example.join(','), example2.join(',')].join('\n');
      this.downloadBlob(csv, 'employee-template.csv');
      return;
    }

    const header = this.parsedRows[0];
    const csv = [header.join(',')];
    // 追加单行示例
    const sample = header.map((h, i) => `示例${i + 1}`);
    csv.push(sample.join(','));
    this.downloadBlob(csv.join('\n'), 'employee-template.csv');
  }

  private downloadBlob(content: string, filename: string): void {
    const blob = new Blob([content], {type: 'text/csv;charset=utf-8;'});
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    a.click();
    window.URL.revokeObjectURL(url);
  }

  private reset(): void {
    this.fileName = '';
    this.parsedRows = [];
    this.parsedPayload = null;
  }

  private resetFileState(): void {
    this.fileName = '';
    this.parsedRows = [];
    this.parsedPayload = null;
  }
}